package com.xinzhu.twitter.app;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Type;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;

import android.app.ListActivity;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.SimpleAdapter;

public class MainActivity extends ListActivity {
	private ArrayList<Map<String, Object>> publicTimeline;

	private SimpleAdapter mTweets;
	private ProgressDialog dialog;

	Handler mHandler = new Handler();

	private static final int MENU_REFRESH = Menu.FIRST;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		publicTimeline = new ArrayList<Map<String, Object>>();
		mTweets = new SimpleAdapter(this, publicTimeline, R.layout.item,
				new String[] { "twitterid", "message", "img" }, new int[] {
						R.id.twitterid, R.id.message, R.id.img });

		mTweets.setViewBinder(new MyViewBinder());

		setListAdapter(mTweets);
		updatePublicTimeline();
	}

	protected void updatePublicTimeline() {
		dialog = ProgressDialog.show(MainActivity.this, "", "しばらくお待ちください...",
				true);

		Thread updateThread = new Thread(null, backgroundRefresh,
				"refresh_actionHistory");
		updateThread.start();
	}

	private Runnable backgroundRefresh = new Runnable() {
		public void run() {
			updateListView();
		}
	};

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {

		menu.add(0, MENU_REFRESH, Menu.NONE, R.string.menu_refresh).setIcon(
				android.R.drawable.ic_menu_recent_history);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		super.onOptionsItemSelected(item);
		switch (item.getItemId()) {
		case MENU_REFRESH:
			updatePublicTimeline();
			return true;
		}
		return false;
	}

	/**
	 * InputStreamからStringへ変換する
	 */
	public String convertStreamToString(InputStream is) throws IOException {
		if (is != null) {
			Writer writer = new StringWriter();

			char[] buffer = new char[1024];
			try {
				Reader reader = new BufferedReader(new InputStreamReader(is,
						"UTF-8"));
				int n;
				while ((n = reader.read(buffer)) != -1) {
					writer.write(buffer, 0, n);
				}
			} finally {
				is.close();
			}
			return writer.toString();
		} else {
			return "";
		}
	}

	private Bitmap LoadImage(String URL, BitmapFactory.Options options) {
		Bitmap bitmap = null;
		InputStream in = null;
		try {
			in = OpenHttpConnection(URL);
			bitmap = BitmapFactory.decodeStream(in, null, options);
			in.close();
		} catch (IOException e1) {
		}
		return bitmap;
	}

	private InputStream OpenHttpConnection(String strURL) throws IOException {
		InputStream inputStream = null;
		URL url = new URL(strURL);
		URLConnection conn = url.openConnection();

		try {
			HttpURLConnection httpConn = (HttpURLConnection) conn;
			httpConn.setRequestMethod("GET");
			httpConn.connect();

			if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
				inputStream = httpConn.getInputStream();
			}
		} catch (Exception ex) {
		}
		return inputStream;
	}

	private void updateListView() {

		try {

			String locationFeed = "http://api.twitter.com/1/statuses/public_timeline.json";

			HttpParams httpParams = new BasicHttpParams();
			HttpConnectionParams.setConnectionTimeout(httpParams, 2000); // 接続のタイムアウト
			HttpConnectionParams.setSoTimeout(httpParams, 2000); // データ取得のタイムアウト
			HttpClient objHttp = new DefaultHttpClient(httpParams);

			HttpGet objGet = new HttpGet(locationFeed);
			HttpResponse objResponse = objHttp.execute(objGet);

			if (objResponse.getStatusLine().getStatusCode() == HttpURLConnection.HTTP_OK) {

				// HTTP_OKであった場合
				InputStream objStream = objResponse.getEntity().getContent();
				String jsonString = convertStreamToString(objStream);

				Type type = new TypeToken<List<Tweet>>() {
				}.getType();

				GsonBuilder gsonBuilder = new GsonBuilder();
				Gson gson = gsonBuilder.create();

				List<Tweet> locationList = gson.fromJson(jsonString, type);

				Map<String, Object> data;

				publicTimeline.clear();

				for (Tweet tw : locationList) {
					data = new HashMap<String, Object>();

					String twitterid = tw.getUser().getName();
					String message = tw.getText();
					String imageUrl = tw.getUser().getProfileImageUrl();

					BitmapFactory.Options bmOptions;
					bmOptions = new BitmapFactory.Options();
					bmOptions.inSampleSize = 1;
					Bitmap bmp = LoadImage(imageUrl, bmOptions);

					data.put("twitterid", twitterid);
					data.put("message", message);
					data.put("img", bmp);
					publicTimeline.add(data);
				}

				mHandler.post(new Runnable() {
					public void run() {

						// リストに変更があった事を通知
						mTweets.notifyDataSetChanged();
						dialog.dismiss();
					}

				});
			}

		} catch (IOException e) {
			e.printStackTrace();
		} finally {
		}
	}
}